本文转自:
续上一篇的文章:
自从认识某人后,我收获了两个成功。登录成功、付款成功,而且还拥有了自己的一辆车:
购物车
也发现了自己的不足之处:
余额不足。
为大家介绍的就是购物车
这里演示从商品列表中添加到购物车
下面先做商品列表页。如下图:
布局分析:
首先一个list的主盒子,接着是item盒子,这是必须的。 然后把item分成左侧的图片部分,和右侧的说明部分(item盒子使用横向弹性盒) 右侧的说明部分又分上下2部分(右侧说明部分盒子使用纵向弹性盒) 下面价钱购物车部分(下面价钱购物车部分也使用横向弹性盒,中间使用justify-content: space-between;填充空白)
index.wxml:
- <!--主盒子-->
- <view class="container">
- <!--head-->
- <view class="tit">
- <view class="title_val">商品列表</view>
- <view class="more">更多</view>
- </view>
- <!--list-->
- <view class="goodslist">
- <!--item-->
- <block wx:for="{ {goodslist}}">
- <view class="goods">
- <!--左侧图片盒子-->
- <view>
- <image src="{ {item.imgUrl}}" class="good-img" />
- </view>
- <!--右侧说明部分-->
- <view class="good-cont">
- <!--上--文字说明-->
- <view class="goods-navigator">
- <text class="good-name">{ {item.name}}</text>
- </view>
- <!--下--价格部分-->
- <view class="good-price">
- <text>¥{ {item.price}}</text>
- <image id="{ {item.id}}" class="cart" src="/images/new_73.jpg" bindtap="addcart" />
- </view>
- </view>
- </view>
- </block>
- </view>
- </view>
商品列表 更多 { {item.name}} ¥{ {item.price}}
index.wxss:
- /**index.wxss**/
- page{
- height: 100%;
- }
- .container{
- background: #f5f5f5;
- }
- .tit{
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- height: 30px;
- position: relative;
- }
- .tit::before{
- content:'';
- background: #ffcc00;
- width:5px;
- height: 100%;
- position: absolute;
- left: 0;
- top: 0;
- }
- .title_val{
- padding: 0 15px;
- font-size: 14px;
- color: #555;
- line-height: 30px;
- }
- .more{
- font-size: 12px;
- line-height: 30px;
- color: #999;
- padding: 0 5px 0 0 ;
- }
- .goodslist{
- background: #fff;
- display: flex;
- flex-direction: column;
- }
- .goods{
- display: flex;
- flex-direction: row;
- border-bottom: 1px solid #ddd;
- }
- .good-img{
- padding: 5px;
- width: 80px;
- height: 80px;
- }
- .good-cont{
- display: flex;
- flex: 1;
- flex-direction: column;
- font-size: 14px;
- }
- .goods-navigator{
- display: flex;
- flex: 1;
- flex-direction: column;
- justify-content: center;
- }
- .good-name{
- display: flex;
- flex: 1;
- flex-direction: column;
- color: #555;
- justify-content: center;
- }
- .good-price{
- display: flex;
- flex: 1;
- flex-direction: row;
- justify-content: space-between;
- color:#e4393c;
- font-weight: 600;
- }
- .cart{
- width: 40px;
- height: 40px;
- padding-right: 10px;
- }
/**index.wxss**/page{ height: 100%;}.container{ background: #f5f5f5;}.tit{ display: flex; flex-direction: row; justify-content: space-between; height: 30px; position: relative;}.tit::before{ content:''; background: #ffcc00; width:5px; height: 100%; position: absolute; left: 0; top: 0;}.title_val{ padding: 0 15px; font-size: 14px; color: #555; line-height: 30px;}.more{ font-size: 12px; line-height: 30px; color: #999; padding: 0 5px 0 0 ;}.goodslist{ background: #fff; display: flex; flex-direction: column;}.goods{ display: flex; flex-direction: row; border-bottom: 1px solid #ddd;}.good-img{ padding: 5px; width: 80px; height: 80px;}.good-cont{ display: flex; flex: 1; flex-direction: column; font-size: 14px;}.goods-navigator{ display: flex; flex: 1; flex-direction: column; justify-content: center;}.good-name{ display: flex; flex: 1; flex-direction: column; color: #555; justify-content: center;}.good-price{ display: flex; flex: 1; flex-direction: row; justify-content: space-between; color:#e4393c; font-weight: 600;}.cart{ width: 40px; height: 40px; padding-right: 10px;}
index.js:
数据部分,一般情况都是访问接口获取数据的,这里并没有使用网络访问,为了简化demo,直接把一组数据放在data对象中。同学们可以根据其数据结构自己编写后台接口
- Page({
- data: {
- goodslist: [
- {
- id:"001",
- imgUrl:"http://img5.imgtn.bdimg.com/it/u=2906541843,1492984080&fm=23&gp=0.jpg",
- name:"女装T恤中长款大码摆裙春夏新款",
- price:"65.00"
- },
- {
- id:"002",
- imgUrl:"http://img4.imgtn.bdimg.com/it/u=1004404590,1607956492&fm=23&gp=0.jpg",
- name:"火亮春秋季 男青年修身款圆领男士T恤",
- price:"68.00"
- },
- {
- id:"003",
- imgUrl:"http://img1.imgtn.bdimg.com/it/u=2305064940,3470659889&fm=23&gp=0.jpg",
- name:"新款立体挂脖t恤女短袖大码宽松条纹V领上衣显瘦休闲春夏",
- price:"86.00"
- },
- {
- id:"004",
- imgUrl:"http://img4.imgtn.bdimg.com/it/u=3986819380,1610061022&fm=23&gp=0.jpg",
- name:"男运动上衣春季上新品 上衣流行装青年",
- price:"119.00"
- },
- {
- id:"005",
- imgUrl:"http://img1.imgtn.bdimg.com/it/u=3583238552,3525141111&fm=23&gp=0.jpg",
- name:"时尚字母三角露胸t恤女装亮丝大码宽松不规则春夏潮",
- price:"69.00"
- },
- {
- id:"006",
- imgUrl:"http://img2.imgtn.bdimg.com/it/u=1167272381,3361826143&fm=23&gp=0.jpg",
- name:"新款立体挂脖t恤短袖大码宽松条纹V领上衣显瘦休闲春夏",
- price:"86.00"
- },
- {
- id:"007",
- imgUrl:"http://img0.imgtn.bdimg.com/it/u=789486313,2033571593&fm=23&gp=0.jpg",
- name:"时尚字母三角露胸t恤女装亮丝大码宽松不规则春夏潮",
- price:"119.00"
- },
- {
- id:"008",
- imgUrl:"http://img2.imgtn.bdimg.com/it/u=3314044863,3966877419&fm=23&gp=0.jpg",
- name:"男运动上衣春季上新品 上衣流行装青年",
- price:"69.00"
- },
- ]
- },
- // 加入购物车
- addcart:function(e){
- this.setData({
- toastHidden:false
- });
- // 遍历列表 与 购物车列表
- for (var i in this.data.goodslist){
- // 列表中某一项item的id == 点击事件传递过来的id。则是被点击的项
- if(this.data.goodslist[i].id == e.target.id){
- // 给goodsList数组的当前项添加count元素,值为1,用于记录添加到购物车的数量
- this.data.goodslist[i].count = 1;
- // 获取购物车的缓存数组(没有数据,则赋予一个空数组)
- var arr = wx.getStorageSync('cart') || [];
- // 如果购物车有数据
- if(arr.length>0){
- // 遍历购物车数组
- for(var j in arr){
- // 判断购物车内的item的id,和事件传递过来的id,是否相等
- if(arr[j].id == e.target.id){
- // 相等的话,给count+1(即再次添加入购物车,数量+1)
- arr[j].count = arr[j].count + 1;
- // 最后,把购物车数据,存放入缓存(此处不用再给购物车数组push元素进去,因为这个是购物车有的,直接更新当前数组即可)
- try {
- wx.setStorageSync('cart', arr)
- } catch (e) {
- console.log(e)
- }
- // 返回(在if内使用return,跳出循环节约运算,节约性能)
- return;
- }
- }
- // 遍历完购物车后,没有对应的item项,把goodslist的当前项放入购物车数组
- arr.push(this.data.goodslist[i]);
- }
- // 购物车没有数据,把item项push放入当前数据(第一次存放时)
- else{
- arr.push(this.data.goodslist[i]);
- }
- // 最后,把购物车数据,存放入缓存
- try {
- wx.setStorageSync('cart', arr)
- // 返回(在if内使用return,跳出循环节约运算,节约性能)
- return;
- } catch (e) {
- console.log(e)
- }
- }
- }
- }
- })
Page({ data: { goodslist: [ { id:"001", imgUrl:"http://img5.imgtn.bdimg.com/it/u=2906541843,1492984080&fm=23&gp=0.jpg", name:"女装T恤中长款大码摆裙春夏新款", price:"65.00" }, { id:"002", imgUrl:"http://img4.imgtn.bdimg.com/it/u=1004404590,1607956492&fm=23&gp=0.jpg", name:"火亮春秋季 男青年修身款圆领男士T恤", price:"68.00" }, { id:"003", imgUrl:"http://img1.imgtn.bdimg.com/it/u=2305064940,3470659889&fm=23&gp=0.jpg", name:"新款立体挂脖t恤女短袖大码宽松条纹V领上衣显瘦休闲春夏", price:"86.00" }, { id:"004", imgUrl:"http://img4.imgtn.bdimg.com/it/u=3986819380,1610061022&fm=23&gp=0.jpg", name:"男运动上衣春季上新品 上衣流行装青年", price:"119.00" }, { id:"005", imgUrl:"http://img1.imgtn.bdimg.com/it/u=3583238552,3525141111&fm=23&gp=0.jpg", name:"时尚字母三角露胸t恤女装亮丝大码宽松不规则春夏潮", price:"69.00" }, { id:"006", imgUrl:"http://img2.imgtn.bdimg.com/it/u=1167272381,3361826143&fm=23&gp=0.jpg", name:"新款立体挂脖t恤短袖大码宽松条纹V领上衣显瘦休闲春夏", price:"86.00" }, { id:"007", imgUrl:"http://img0.imgtn.bdimg.com/it/u=789486313,2033571593&fm=23&gp=0.jpg", name:"时尚字母三角露胸t恤女装亮丝大码宽松不规则春夏潮", price:"119.00" }, { id:"008", imgUrl:"http://img2.imgtn.bdimg.com/it/u=3314044863,3966877419&fm=23&gp=0.jpg", name:"男运动上衣春季上新品 上衣流行装青年", price:"69.00" }, ] }, // 加入购物车 addcart:function(e){ this.setData({ toastHidden:false }); // 遍历列表 与 购物车列表 for (var i in this.data.goodslist){ // 列表中某一项item的id == 点击事件传递过来的id。则是被点击的项 if(this.data.goodslist[i].id == e.target.id){ // 给goodsList数组的当前项添加count元素,值为1,用于记录添加到购物车的数量 this.data.goodslist[i].count = 1; // 获取购物车的缓存数组(没有数据,则赋予一个空数组) var arr = wx.getStorageSync('cart') || []; // 如果购物车有数据 if(arr.length>0){ // 遍历购物车数组 for(var j in arr){ // 判断购物车内的item的id,和事件传递过来的id,是否相等 if(arr[j].id == e.target.id){ // 相等的话,给count+1(即再次添加入购物车,数量+1) arr[j].count = arr[j].count + 1; // 最后,把购物车数据,存放入缓存(此处不用再给购物车数组push元素进去,因为这个是购物车有的,直接更新当前数组即可) try { wx.setStorageSync('cart', arr) } catch (e) { console.log(e) } // 返回(在if内使用return,跳出循环节约运算,节约性能) return; } } // 遍历完购物车后,没有对应的item项,把goodslist的当前项放入购物车数组 arr.push(this.data.goodslist[i]); } // 购物车没有数据,把item项push放入当前数据(第一次存放时) else{ arr.push(this.data.goodslist[i]); } // 最后,把购物车数据,存放入缓存 try { wx.setStorageSync('cart', arr) // 返回(在if内使用return,跳出循环节约运算,节约性能) return; } catch (e) { console.log(e) } } } }})
编写购物车部分,如下图所示:
布局分析:
首先一个list的主盒子,接着是item盒子,这是必须的。
然后把item分成左侧的图片部分,和右侧的说明部分(item盒子使用横向弹性盒)
右侧的说明部分又分上下2部分(右侧说明部分盒子使用纵向弹性盒)
下面价钱、购物加减、购物车部分(使用纵向弹性盒)
最下面的购物加减、购物车部分(使用横向弹性盒,中间使用justify-content: space-between;填充空白)
cart.wxml:
- <!--要是够车内没有数据,就行显示没有数据-->
- <view class="cart" hidden="{ {iscart}}">
- <image src="/images/cart.png"/>
- <view>购物车什么都没有,赶快去购物吧</view>
- </view>
- <!--要是有数据,就显示数据-->
- <view class="cartList" hidden="{ {!iscart}}">
- <!--header-->
- <view class="baoyou"></view>
- <!--list item-->
- <block wx:for="{ {cart}}">
- <view class="goods">
- <!--左侧图片-->
- <view>
- <image src="{ {item.imgUrl}}" class="good-img"/>
- </view>
- <!--右侧说明部分-->
- <view class="good-cont">
- <!--文字说明-->
- <view class="goods-navigator">
- <text class="good-name">{ {item.name}}</text>
- </view>
- <!--价钱和购物加减的父盒子-->
- <view class="good-price">
- <text class="price">¥{ {item.price}}</text>
- <view class="btn-box">
- <view class="btn">
- <button id="del{ {index}}" type="default" size="mini" bindtap="delCount">-</button>
- <input value="{ {item.count}}"/>
- <button id="add{ {index}}" type="default" size="mini" bindtap="addCount">+</button>
- </view>
- <image id="img{ {index}}" src="/images/del2.png" bindtap="delGoods"/>
- </view>
- </view>
- </view>
- </view>
- </block>
- <!--footer-->
- <view class="total">
- <view class="total_text">合计:<text>¥{ {total}}</text></view>
- <button class="total_js" size="mini">去结算({ {goodsCount}})</button>
- </view>
- </view>
购物车什么都没有,赶快去购物吧 { {item.name}} ¥{ {item.price}} 合计: ¥{ {total}}
cart.wxss:
- page {
- background: #f2ebe3;
- }
- .cart {
- padding: 100px 0 0 0;
- display: flex;
- justify-content: center;
- flex-direction: column;
- align-items: center;
- color: #999;
- }
- .cart image {
- width: 66px;
- height: 66px;
- margin-bottom: 20px;
- }
- .baoyou {
- font-size: 18px;
- color: #db2929;
- padding: 10px;
- }
- .goods {
- background: #fff;
- border-top: 1px solid #ddd;
- margin-bottom: 10px;
- padding: 10px 10px 0 10px;
- display: flex;
- }
- .goods image {
- width: 80px;
- height: 80px;
- border: 1px solid #ddd;
- }
- .goods .good-cont {
- display: flex;
- flex: 1;
- flex-direction: column;
- color: #555;
- font-size: 14px;
- padding: 5px;
- height: 100px;
- }
- .goods .good-cont .goods-navigator {
- display: flex;
- flex: 2;
- }
- .goods .good-cont .good-price {
- display: flex;
- flex-direction: column;
- flex: 3;
- }
- .goods .good-cont .good-price .price {
- font-size: 16px;
- color: #ec5151;
- }
- .goods .good-cont .good-price .btn-box {
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- }
- .goods .good-cont .good-price .btn-box image {
- width: 23px;
- height: 23px;
- border: 0;
- margin: 0;
- }
- .goods .good-cont .good-price .btn {
- display: flex;
- flex-direction: row;
- }
- .goods .good-cont .good-price .btn input {
- margin: 0;
- width: 40px;
- text-align: center;
- border: 1px solid #eee;
- font-size: 16px;
- height: 28px;
- }
- .goods .good-cont .good-price .btn button {
- margin: 0;
- }
- .total {
- height: 40px;
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- padding: 0 20px;
- }
- .total .total_text {
- display: flex;
- color: #777;
- }
- .total .total_text text {
- color: #ec5151;
- }
- .total .total_js {
- color: #fff;
- background: #ec5151;
- height: 30px;
- margin: 0;
- }
page { background: #f2ebe3;}.cart { padding: 100px 0 0 0; display: flex; justify-content: center; flex-direction: column; align-items: center; color: #999;}.cart image { width: 66px; height: 66px; margin-bottom: 20px;}.baoyou { font-size: 18px; color: #db2929; padding: 10px;}.goods { background: #fff; border-top: 1px solid #ddd; margin-bottom: 10px; padding: 10px 10px 0 10px; display: flex;}.goods image { width: 80px; height: 80px; border: 1px solid #ddd;}.goods .good-cont { display: flex; flex: 1; flex-direction: column; color: #555; font-size: 14px; padding: 5px; height: 100px;}.goods .good-cont .goods-navigator { display: flex; flex: 2;}.goods .good-cont .good-price { display: flex; flex-direction: column; flex: 3;}.goods .good-cont .good-price .price { font-size: 16px; color: #ec5151;}.goods .good-cont .good-price .btn-box { display: flex; flex-direction: row; justify-content: space-between;}.goods .good-cont .good-price .btn-box image { width: 23px; height: 23px; border: 0; margin: 0;}.goods .good-cont .good-price .btn { display: flex; flex-direction: row;}.goods .good-cont .good-price .btn input { margin: 0; width: 40px; text-align: center; border: 1px solid #eee; font-size: 16px; height: 28px;}.goods .good-cont .good-price .btn button { margin: 0;}.total { height: 40px; display: flex; flex-direction: row; justify-content: space-between; padding: 0 20px;}.total .total_text { display: flex; color: #777;}.total .total_text text { color: #ec5151;}.total .total_js { color: #fff; background: #ec5151; height: 30px; margin: 0;}
cart.js:
- Page({
- data: {
- iscart: false,
- cart: [], //数据
- count: 1, //商品数量默认是1
- total: 0, //总金额
- goodsCount: 0 //数量
- },
- onLoad: function (options) {
- },
- onShow: function () {
- var that = this;
- // 获取产品展示页保存的缓存数据(购物车的缓存数组,没有数据,则赋予一个空数组)
- var arr = wx.getStorageSync('cart') || [];
- // 有数据的话,就遍历数据,计算总金额 和 总数量
- if (arr.length > 0) {
- for (var i in arr) {
- that.data.total += Number(arr[i].price) * Number(arr[i].count);
- that.data.goodsCount += Number(arr[i].count);
- }
- // 更新数据
- this.setData({
- iscart: true,
- cart: arr,
- total: that.data.total,
- goodsCount: that.data.goodsCount
- });
- }
- },
- onHide: function(){
- // 清除数据
- this.setData({
- iscart: false,
- cart: [], //数据
- total: 0, //总金额
- goodsCount: 0 //数量
- });
- },
- /* 减数 */
- delCount: function (e) {
- console.log(e)
- // 获取购物车该商品的数量
- // [获取设置在该btn的id,即list的index值]
- if (this.data.cart[e.target.id.substring(3)].count <= 1) {
- return;
- }
- // 商品总数量-1
- this.data.goodsCount -= 1;
- // 总价钱 减去 对应项的价钱单价
- this.data.total -= Number(this.data.cart[e.target.id.substring(3)].price);
- // 购物车主体数据对应的项的数量-1 并赋给主体数据对应的项内
- this.data.cart[e.target.id.substring(3)].count = --this.data.cart[e.target.id.substring(3)].count;
- // 更新data数据对象
- this.setData({
- cart: this.data.cart,
- total: this.data.total,
- goodsCount: this.data.goodsCount
- })
- // 主体数据重新赋入缓存内
- try {
- wx.setStorageSync('cart', this.data.cart)
- } catch (e) {
- console.log(e)
- }
- },
- /* 加数 */
- addCount: function (e) {
- // 商品总数量+1
- this.data.goodsCount += 1;
- // 总价钱 加上 对应项的价钱单价
- this.data.total += Number(this.data.cart[e.target.id.substring(3)].price);
- // 购物车主体数据对应的项的数量+1 并赋给主体数据对应的项内
- this.data.cart[e.target.id.substring(3)].count = ++this.data.cart[e.target.id.substring(3)].count;
- // 更新data数据对象
- this.setData({
- cart: this.data.cart,
- total: this.data.total,
- goodsCount: this.data.goodsCount
- })
- // 主体数据重新赋入缓存内
- try {
- wx.setStorageSync('cart', this.data.cart)
- } catch (e) {
- console.log(e)
- }
- },
- /* 删除item */
- delGoods: function (e) {
- // 商品总数量 减去 对应删除项的数量
- this.data.goodsCount = this.data.goodsCount - this.data.cart[e.target.id.substring(3)].count;
- // 总价钱 减去 对应删除项的单价*数量
- this.data.total -= this.data.cart[e.target.id.substring(3)].price * this.data.cart[e.target.id.substring(3)].count;
- // 主体数据的数组移除该项
- this.data.cart.splice(e.target.id.substring(3), 1);
- // 更新data数据对象
- this.setData({
- cart: this.data.cart,
- total: this.data.total,
- goodsCount: this.data.goodsCount
- })
- // 主体数据重新赋入缓存内
- try {
- wx.setStorageSync('cart', this.data.cart)
- } catch (e) {
- console.log(e)
- }
- }
- })
Page({ data: { iscart: false, cart: [], //数据 count: 1, //商品数量默认是1 total: 0, //总金额 goodsCount: 0 //数量 }, onLoad: function (options) { }, onShow: function () { var that = this; // 获取产品展示页保存的缓存数据(购物车的缓存数组,没有数据,则赋予一个空数组) var arr = wx.getStorageSync('cart') || []; // 有数据的话,就遍历数据,计算总金额 和 总数量 if (arr.length > 0) { for (var i in arr) { that.data.total += Number(arr[i].price) * Number(arr[i].count); that.data.goodsCount += Number(arr[i].count); } // 更新数据 this.setData({ iscart: true, cart: arr, total: that.data.total, goodsCount: that.data.goodsCount }); } }, onHide: function(){ // 清除数据 this.setData({ iscart: false, cart: [], //数据 total: 0, //总金额 goodsCount: 0 //数量 }); }, /* 减数 */ delCount: function (e) { console.log(e) // 获取购物车该商品的数量 // [获取设置在该btn的id,即list的index值] if (this.data.cart[e.target.id.substring(3)].count <= 1) { return; } // 商品总数量-1 this.data.goodsCount -= 1; // 总价钱 减去 对应项的价钱单价 this.data.total -= Number(this.data.cart[e.target.id.substring(3)].price); // 购物车主体数据对应的项的数量-1 并赋给主体数据对应的项内 this.data.cart[e.target.id.substring(3)].count = --this.data.cart[e.target.id.substring(3)].count; // 更新data数据对象 this.setData({ cart: this.data.cart, total: this.data.total, goodsCount: this.data.goodsCount }) // 主体数据重新赋入缓存内 try { wx.setStorageSync('cart', this.data.cart) } catch (e) { console.log(e) } }, /* 加数 */ addCount: function (e) { // 商品总数量+1 this.data.goodsCount += 1; // 总价钱 加上 对应项的价钱单价 this.data.total += Number(this.data.cart[e.target.id.substring(3)].price); // 购物车主体数据对应的项的数量+1 并赋给主体数据对应的项内 this.data.cart[e.target.id.substring(3)].count = ++this.data.cart[e.target.id.substring(3)].count; // 更新data数据对象 this.setData({ cart: this.data.cart, total: this.data.total, goodsCount: this.data.goodsCount }) // 主体数据重新赋入缓存内 try { wx.setStorageSync('cart', this.data.cart) } catch (e) { console.log(e) } }, /* 删除item */ delGoods: function (e) { // 商品总数量 减去 对应删除项的数量 this.data.goodsCount = this.data.goodsCount - this.data.cart[e.target.id.substring(3)].count; // 总价钱 减去 对应删除项的单价*数量 this.data.total -= this.data.cart[e.target.id.substring(3)].price * this.data.cart[e.target.id.substring(3)].count; // 主体数据的数组移除该项 this.data.cart.splice(e.target.id.substring(3), 1); // 更新data数据对象 this.setData({ cart: this.data.cart, total: this.data.total, goodsCount: this.data.goodsCount }) // 主体数据重新赋入缓存内 try { wx.setStorageSync('cart', this.data.cart) } catch (e) { console.log(e) } }})
运行结果:
demo:
更多小程序的教程
更多小程序的教程请查看:
谢谢观看,不足之处,敬请指导